﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using System.Windows.Threading;
using System.Windows.Forms;
using System.Collections.ObjectModel;

namespace Mosiac_Desktop
{
    /// <summary>
    /// Interaction logic for Window1.xaml
    /// </summary>
    public partial class Window1 : Window
    {
        public delegate void NextImageDelegate();
        protected WallpaperData oWallpaperData;
        private DispatcherTimer oTimer;
        private FolderBrowserDialog oFolderDialog;
        private const String oDataStore = "data.bin";
        private List<string> m_oFolders;
        private System.Windows.Forms.NotifyIcon m_notifyIcon;
        private Color m_oNormalColor = Color.FromArgb(144, 255, 255, 255);
        private Color m_oHighlitedColor = Color.FromArgb(255, 255, 255, 255);


        public string ConstraintValue
        {
            get { return oWallpaperData.ConstraintValue.ToString(); }
            set { 
                oWallpaperData.ConstraintValue = int.Parse(value);
                Serialize();
            }
        }
        public string TimerValue
        {
            get { return oWallpaperData.TimerValue.ToString(); }
            set
            {
                oWallpaperData.TimerValue = int.Parse(value);
                Serialize();
            }
        }
        public bool UseSubdirectories
        {
            get { return oWallpaperData.UseSubdirectories; }
            set { 
                oWallpaperData.UseSubdirectories = value;
                Serialize();
            }
        }

        public static List<T> EnumToList<T>()
        {
         Type enumType = typeof(T);
         if (enumType.BaseType != typeof(Enum))
          throw new ArgumentException("T must be of type System.Enum");

         return new List<T>(Enum.GetValues(enumType) as IEnumerable<T>);
        }
        
        public List<string> ConstraintStyle
        {
            get {
                List<string> oL = new List<string>();
                foreach(Wallpaper.Constraint oC in EnumToList<Wallpaper.Constraint>())
                {
                    oL.Add(oC == Wallpaper.Constraint.Height ? "Height" : "Width");
                }
                return oL;
            }
        }
                
        public Window1()
        {

            InitializeComponent();
            m_notifyIcon = new System.Windows.Forms.NotifyIcon();
            m_notifyIcon.BalloonTipText = "Mosaic Desktop has been minimised. Click the tray icon to show.";
            m_notifyIcon.BalloonTipTitle = "Mosaic Desktop";
            m_notifyIcon.Text = "Mosaic Desktop";
            m_notifyIcon.Icon = new System.Drawing.Icon("MC.ico");
            m_notifyIcon.Click += new EventHandler(m_notifyIcon_Click);

            oTimer = new DispatcherTimer();
            oTimer.Stop();

            oWallpaperData = new WallpaperData();
            CB_ConstraintType.SelectedIndex = 0;
            DeSerialize();
            Inputs.ItemsSource = oWallpaperData.Directories;
            CB_ConstraintType.ItemsSource = ConstraintStyle;
            DataContext = this;
            CB_ConstraintType.SelectionChanged += new SelectionChangedEventHandler(CB_ConstraintType_SelectionChanged);
            CB_ConstraintType.Text = oWallpaperData.Constraint == Wallpaper.Constraint.Width ? "Width" : "Height";


            oTimer.Interval = new TimeSpan(0, oWallpaperData.TimerValue, 0);
            oTimer.Tick += new EventHandler(oTimer_Tick);
            if (!oTimer.IsEnabled && oWallpaperData.TimerValue > 0)
                oTimer.Start();

            oFolderDialog = new FolderBrowserDialog();
        }


        private WindowState m_storedWindowState = WindowState.Normal;
        void OnStateChanged(object sender, EventArgs args)
        {
            if (WindowState == WindowState.Minimized)
            {
                Hide();
                if (m_notifyIcon != null)
                    m_notifyIcon.ShowBalloonTip(2000);
            }
            else
                m_storedWindowState = WindowState;
        }
        void OnIsVisibleChanged(object sender, DependencyPropertyChangedEventArgs args)
        {
            CheckTrayIcon();
        }

        void m_notifyIcon_Click(object sender, EventArgs e)
        {
            Show();
            WindowState = m_storedWindowState;
        }
        void CheckTrayIcon()
        {
            ShowTrayIcon(!IsVisible);
        }

        void ShowTrayIcon(bool show)
        {
            if (m_notifyIcon != null)
                m_notifyIcon.Visible = show;
        }

        void oTimer_Tick(object sender, EventArgs e)
        {
            StartDeskop();
        }

        void CB_ConstraintType_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            Wallpaper.Constraint eC;
            eC = CB_ConstraintType.SelectedValue.ToString() == "Width" ? Wallpaper.Constraint.Width : Wallpaper.Constraint.Height;
            if (eC != oWallpaperData.Constraint)
            {
                oWallpaperData.Constraint = eC;
                Serialize();
            }
        }
       
        private void Serialize()
        {
            try
            {
                using (Stream stream = File.Open(oDataStore, FileMode.Create))
                {
                    BinaryFormatter bin = new BinaryFormatter();
                    bin.Serialize(stream, oWallpaperData);
                }
            }
            catch (IOException)
            {
            }
        }
        private void DeSerialize()
        {
            try
            {
                using (Stream stream = File.Open(oDataStore, FileMode.Open))
                {
                    BinaryFormatter bin = new BinaryFormatter();

                    oWallpaperData = (WallpaperData)bin.Deserialize(stream);
                }
            }
            catch (IOException)
            {
            }
        }

        private void AddInput_Click(object sender, RoutedEventArgs e)
        {

            DialogResult oResult = oFolderDialog.ShowDialog();
            if (oResult == System.Windows.Forms.DialogResult.OK && !Inputs.Items.Contains(this.oFolderDialog.SelectedPath))
            {
                oWallpaperData.Directories.Add(oFolderDialog.SelectedPath);
                Serialize();

            }
        }

        private void Remove_Input_Click(object sender, RoutedEventArgs e)
        {
            while (Inputs.SelectedItems.Count > 0)
            {
                oWallpaperData.Directories.Remove(Inputs.SelectedItems[0].ToString());
            }
            Serialize();
        }

        private void Start_Click(object sender, RoutedEventArgs e)
        {
            StartDeskop();
        }
        private void CreateImage()
        {
             
            Wallpaper oWallPaper = new Wallpaper();
            string oWallpaperFile = oWallPaper.StartDeskop(m_oFolders, oWallpaperData.ConstraintValue, Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height, oWallpaperData.Constraint, oWallpaperData.UseSubdirectories);
            oWallPaper = null;
            if (oWallpaperFile != "")
            {
                BitmapImage oI = new BitmapImage(new Uri(oWallpaperFile));
                WindowFlash oW = new WindowFlash();
                oW.image_wallpaper.Source = oI;
                oW.Top = Screen.PrimaryScreen.Bounds.Height - oW.Height;
                oW.Left = Screen.PrimaryScreen.Bounds.Width - oW.Width;
                oW.Show();
            }
        }

        private void StartDeskop()
        {
            if (oWallpaperData.ConstraintValue == 0)
                return;

            m_oFolders = null;
            m_oFolders = new List<string>();
            foreach (string sDir in oWallpaperData.Directories)
            {
                m_oFolders.Add(sDir);
            }
            Start.Dispatcher.BeginInvoke(
                    DispatcherPriority.Normal,
                    new NextImageDelegate(CreateImage));
            oTimer.Interval = new TimeSpan(0, oWallpaperData.TimerValue, 0);
            if (!oTimer.IsEnabled && oWallpaperData.TimerValue > 0)
                oTimer.Start();
        }

        private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
        {
            m_notifyIcon.Dispose();
            m_notifyIcon = null;
        }

        private void Minimize_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            WindowState = WindowState.Minimized;
        }

        private void Minimize_MouseEnter(object sender, System.Windows.Input.MouseEventArgs e)
        {
            SolidColorBrush oB = (SolidColorBrush)this.MinimizeIcon.Fill;
            oB.Color = (oB.Color == m_oNormalColor) ? m_oHighlitedColor : m_oNormalColor;
            this.MinimizeIcon.Fill = oB;
        }

        private void Canvas_MouseEnter(object sender, System.Windows.Input.MouseEventArgs e)
        {
            SolidColorBrush oB = (SolidColorBrush)this.Restore1.Stroke;
            oB.Color = (oB.Color == m_oNormalColor) ? m_oHighlitedColor : m_oNormalColor;
            this.Restore1.Stroke = oB;
            oB = (SolidColorBrush)this.Restore2.Stroke;
            oB.Color = (oB.Color == m_oNormalColor) ? m_oHighlitedColor : m_oNormalColor;
            this.Restore2.Stroke = oB;
        }

        private void Canvas_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            WindowState = WindowState.Normal;
        }

        private void Close_MouseEnter(object sender, System.Windows.Input.MouseEventArgs e)
        {
            SolidColorBrush oB = (SolidColorBrush)this.ClosePol1.Stroke;
            oB.Color = (oB.Color == m_oNormalColor) ? m_oHighlitedColor : m_oNormalColor;
            this.ClosePol1.Stroke = oB;
            oB = (SolidColorBrush)this.ClosePol2.Stroke;
            oB.Color = (oB.Color == m_oNormalColor) ? m_oHighlitedColor : m_oNormalColor;
            this.ClosePol2.Stroke = oB;
        }

        private void Close_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            if (System.Windows.MessageBox.Show("Are you sure?","Close application?",MessageBoxButton.OKCancel) == MessageBoxResult.OK)
                this.Close();
        }

    }
}
